﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGinnBPM.Lib.Operations;
using NGinnBPM.Lib.Interfaces;
using NGinnBPM.MessageBus;

namespace NGinnBPM.Services.SStack
{
    public class ProcessInformation : 
        IMessageHandlerService<GetProcessSchema>,
        IMessageHandlerService<TestOperation>,
        IMessageHandlerService<GetPackageNames>,
        IMessageHandlerService<StartProcess>,
        IMessageHandlerService<GetProcessNames>,
        IMessageHandlerService<GetTaskInstanceInfo>,
        IMessageHandlerService<CompleteTask>,
        IMessageHandlerService<CancelTask>,
        IMessageHandlerService<UpdateTask>,
        IMessageHandlerService<SelectTask>
    {
        public IProcessPackageRepository ProcessRepository { get; set;  }
        public INGEnvironment Environment { get; set; }

        public object Handle(GetProcessSchema request)
        {
            var pd = ProcessRepository.GetProcess(request.DefinitionId);
            return new GetProcessSchemaResponse { Definition = pd };
        }

        public object Handle(TestOperation request)
        {
            return new TestOperationResponse { D = "test" };
        }

        public object Handle(GetPackageNames request)
        {
            return new GetPackageNamesResponse { Names = ProcessRepository.PackageNames.ToArray() };
        }



        public object Handle(StartProcess request)
        {
            var id = Environment.StartProcess(request.DefinitionId, request.Data, null, null);
            return new StartProcessResponse { InstanceId = id };
        }

        public object Handle(GetProcessNames request)
        {
            var ps = ProcessRepository.GetPackage(request.PackageName).ProcessDefinitionNames;
            return new GetProcessNamesResponse { ProcessNames = ps.ToArray() };
        }

        public object Handle(GetTaskInstanceInfo request)
        {
            var ti = Environment.GetTaskInstanceInformation(request.TaskInstanceId);
            var ret = new GetTaskInstanceInfoResponse();
            ret.Data = ti.TaskData;
            ret.EnabledDate = ti.EnabledDate;
            ret.FinishedDate = ti.FinishedDate;
            ret.ProcessInstanceId = ti.ProcessInstanceId;
            ret.ProcessDefinitionId = ti.ProcessDefinitionId;
            ret.ParentTaskInstanceId = ti.ParentTaskInstanceId;
            ret.Status = ti.Status;
            ret.Success = true;
            ret.TaskId = ti.TaskId;

            return ret;
        }

        public object Handle(CompleteTask request)
        {
            Environment.ForceCompleteTask(request.TaskInstanceId, request.Data, request.CompletedBy);
            return new CompleteTaskResponse { Success = true };
        }

        public object Handle(CancelTask request)
        {
            try
            {
                Environment.CancelTaskInstance(request.TaskInstanceId);
                return new CancelTaskResponse { Success = true };
            }
            catch (Exception ex)
            {
                return new CancelTaskResponse { Success = false, Message = ex.Message };
            }
        }

        public object Handle(UpdateTask request)
        {
            Environment.UpdateTaskData(request.TaskInstanceId, request.Data);
            return new UpdateTaskResponse { Success = true };
        }

        public object Handle(SelectTask request)
        {
            try
            {
                Environment.SelectTask(request.TaskInstanceId);
                return new SelectTaskResponse { Success = true };
            }
            catch (Exception ex)
            {
                return new SelectTaskResponse { Success = false, Message = ex.Message };
            }
        }
    }
}
